/**
 * 
 */
package info.niwota.frames.net;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author qiangli
 *
 */
public class TransportRequestHandler {
	private static ExecutorService pool = Executors.newCachedThreadPool();
	
	private Socket c;
	private ObjectOutputStream out;
	private ObjectInputStream in;

	private TransportResponse resp;
	private TransportRequest req;

	void init(TransportRequest req) throws IOException {
		c = new Socket(req.host, req.port);
		
		OutputStream os = c.getOutputStream();
		os.write(("TRANSPORT " + req.action +" HTTP/1.1\r\n\r\n").getBytes());
		os.flush();
		
		InputStream is = c.getInputStream();
		
		this.out = new ObjectOutputStream(os);
		this.in = new ObjectInputStream(is);
		
		this.req = req;
		this.resp = new TransportResponse();
	}
	
	public TransportResponse process(Object data) throws IOException, ClassNotFoundException {
		req.data = data;
		//
		TransportContext.sendRequest(out, req);
		TransportContext.readResponse(in, resp);
		
		return resp;
	}

	public void startStreaming(InputStream in, OutputStream out) {
		CopyThread t1 = new CopyThread(this.in, out);
		CopyThread t2 = new CopyThread(in, this.out);
		
		pool.execute(t1);
		pool.execute(t2);
	}
	
	public void close() {
		close(in);	
		close(out);	
		close(c);
	}

	private void close(Closeable c) {
		try {
			c.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void close(Socket c) {
		try {
			c.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
